import 'dart:core';

/**
 * 方法
 */

//使用typedef定义方法变量,如同 object，boolean，number 这几种被称为基本类型一样，typedef 的作用是可以自定义一种数据类型，并且这种数据类型属于 函数类型。同时 typedef 可以保留函数签名信息
typedef callback<T> = void Function(T t);

//扩展函数
extension on String {
  printStr() {
    print(this);
  }
}

main() {
  //新特性,空安全
  String s;
  print(s ?? "99");

  var str = "扩展函数";
  str.printStr();

//  print(fun_01());
//  print(fun_02());
  fun_03("zhang", weight: "70kg", age: 18);
  fun_04("zhang", 18, "70kg");

  //使用方法作为参数
  doWhat(String str) {
    print(str);
  }

  doSomeThing(doWhat);
  doSomeThing_2(doWhat);

  //使用方法变量进行回调
  doCallback((res) {
    print(res);
  });

  //也可以这样使用
  callback<dynamic> call = (res) {
    print(res);
  };
  doCallback(call);
  //还可以这样用
  void callBack_2(dynamic res) {
    print(res);
  }

  doCallback(callBack_2);

  doCallback_2(callBack_2);

  var list = [];
  list.add("value");
  print(list.length);

  var list2 = List.filled(10, "haha");
  print(list2.toString());
}

doCallback(callback call) {
  call("你好");
}

doCallback_2(void Function(dynamic res) call) {
  call("你好");
}

/**
 * 使用方法作为参数
 */
doSomeThing(void doWhat(String str)) {
  doWhat("哈哈,果然打印了");
}

/**
 * 还可以这样使用
 */
doSomeThing_2(void Function(String t) doWhat) {
  doWhat("哈哈,果然打印了_2");
}

//开头的int是静态类型定义,表示此方法返回一个int类型的值.可以省略不写.
int fun_01() {
  return 1;
}

//对于只有一个表达式的方法可以简写
//=>相当于return,后面只能使用表达式,不能使用语句
fun_02() => fun_01() + 1;

//参数name为必选参数,{}中的参数为可选参数,{}定义的可选参数在调用时必须指明给定的值是哪个参数的
fun_03(var name, {int age = 1, String weight = "100"}) {
  print("您好:$name!您的年龄是:${age}岁,体重是${weight}");
}

//参数name为必选参数,[]中的参数为可选参数,[]定义的可选参数在调用时需要按照定义的顺序进行赋值.
//因为调用赋值是基于位置的,如果想要给weight赋值,则必须给age赋值
fun_04(var name, [int age = 1, String weight = "100"]) {
  print("您好:$name!您的年龄是:${age}岁,体重是${weight}");
}

void fun_05() {}
